/**
 * 
 */
package com.runningfox.logic;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;

import android.util.Log;

/**
 * @author luhaiyang
 * 
 */
public class Cache {
	/**
	 * cache limits for 50 pages
	 */
	final int MAX = 50;
	static Cache instance;
	// Context c ;
	public static File DIR;
	public static File HOME;

	private Cache() {
	}

	public static Cache getInstance() {
		if (instance == null) {
			instance = new Cache();
		}
		return instance;
	}

	/**
	 * 将字符串保存为文件 如果文件存在，覆盖已存在的同名文件
	 * 
	 * @param key
	 * @param data
	 */
	public void putString(String key, String data) {
		this.manageDir(DIR);
		try {
			StreamToolBox.saveStringToFile(data, this.genFileName(key));
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public void putStream(String key, InputStream in) {
		try {
			StreamToolBox.saveStreamToFile(in, this.genFileName(key));
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	/**
	 * 从文件中读取字符串
	 * 
	 * @param key
	 * @return
	 */
	public String getString(String key) {
		try {
			return StreamToolBox.loadStringFromFile(this.genFileName(key));
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}

	public String getStringFromGzipFile(String key) {
		try {
			InputStream is = StreamToolBox.loadStreamFromGzipFile(this
					.genFileName(key));
			if (is == null) {
				return null;
			} else {
				return StreamToolBox.loadStringFromStream(is);
			}
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}

	public InputStream getHome(String word) {
		String wordHash = MD5Calculator.calculateMD5(word);
		String fileName = HOME.getAbsolutePath() + File.separator + wordHash;
		return StreamToolBox.loadStreamFromFile(fileName);
	}

	public void setHome(String word, InputStream is) {
		String wordHash = MD5Calculator.calculateMD5(word);
		String fileName = HOME.getAbsolutePath() + File.separator + wordHash;
		try {
			StreamToolBox.saveStreamToFile(is, fileName);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public InputStream getInputStream(String key) {
		return StreamToolBox.loadStreamFromFile(this.genFileName(key));
	}

	private String genFileName(String word) {
		String wordHash = MD5Calculator.calculateMD5(word);
		return DIR.getAbsolutePath() + File.separator + wordHash;
	}

	/**
	 * 整理缓存目录 如果超过上限，删除最旧的。
	 * 
	 * @param dir
	 */
	private void manageDir(File dir) {
		if (!dir.isDirectory()) {
			return;
		}
		File[] files = dir.listFiles();
		Log.v("cache size", "" + files.length);
		if (files.length > MAX) {
			File oldest = files[0];
			for (int i = 0; i < files.length; i++) {
				Log.v("loop",  this.getClass().getName()+" manageDir");
				if (oldest.lastModified() > files[i].lastModified()) {
					oldest = files[i];
				}
			}
			String fileName = oldest.getAbsolutePath();
			Log.v("cache delete", fileName);
			oldest.delete();
		}
	}

	public void clear() {
		File[] files = DIR.listFiles();
		Log.v("cache size", "" + files.length);
		for (int i = 0; i < files.length; i++) {
			Log.v("loop",  this.getClass().getName()+" clean");
			files[i].delete();
		}
	}

	/**
	 * 返回缓存大小 byte单位
	 * 
	 * @return
	 */

	public int getSize() {
		File[] files = DIR.listFiles();
		int size = 0;
		Log.v("cache size", "" + files.length);
		for (int i = 0; i < files.length; i++) {
			Log.v("loop",  this.getClass().getName()+" getSize()");
			FileInputStream fis;
			try {
				fis = new FileInputStream(files[i]);
				size += fis.available();
			} catch (FileNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		return size;
	}

	static String SDDIR = "//sdcard/humor/";

	/**
	 * 从sd卡中读取图片，如果没有则从网络下载并保存到sd卡设备中。
	 * 返回地址//sdcard/humor/xxxx
	 * @param url
	 * @return
	 */
	public String getCacheImage(String url) {
		// TODO Auto-generated method stub
		String fileName = SDDIR + MD5Calculator.calculateMD5(url);
		File f = new File(fileName);
		if (f.exists()) {
			Log.v("cache", "image cache hit");
			return fileName;
		} else {
			Log.v("cache", "image cache miss!!!!");
			try {
				InputStream in = StreamToolBox.loadStreamFromURL(url, null);
				String path = StreamToolBox.saveStreamToFileSD(in, fileName);
				return  path;
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			return null;
		}
	}
}
